package com.etooling.pdm.controller;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.etooling.framework.jpa.JpaQueryBuilder;
import com.etooling.framework.jpa.Sorts;
import com.etooling.framework.jpa.Specifications;
import com.etooling.framework.repository.AttachFileRepository;
import com.etooling.framework.repository.ImportDataBatchRepository;
import com.etooling.framework.svo.ReplyObj;
import com.etooling.framework.utils.WebUtils;
import com.etooling.pdm.dto.GoodsSpecsDTO;
import com.etooling.pdm.entity.Goods;
import com.etooling.pdm.entity.GoodsSpecs;
import com.etooling.pdm.entity.GoodsSpecsPropSetting;
import com.etooling.pdm.mapper.PdmMapper;
import com.etooling.pdm.repository.*;
import com.etooling.pdm.service.GoodsService;
import com.etooling.pdm.service.GoodsSpecsService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @author dyz
 * @date 2023/4/12 10:20
 * @description GoodsSpecsController
 */
@RequestMapping(value = "/admin/pdm/goodsSpecs")
@Controller
@EnableAutoConfiguration
public class GoodsSpecsController {
    @Autowired
    private GoodsSpecsRepository goodsSpecsRepository;
    @Autowired
    private GoodsRepository goodsRepository;
    @Autowired
    GoodsService goodsService;
    @Autowired
    private GoodsSpecsService goodsSpecsService;
    @Autowired
    PdmMapper pdmMapper;
    @Autowired
    AttachFileRepository attachFileRepository;
    @Autowired
    GoodsPropValuesRepository goodsPropValuesRepository;
    @Autowired
    ImportDataBatchRepository importDataBatchRepository;
    @Autowired
    GoodsSpecsPropSettingRepository goodsSpecsPropSettingRepository;
    @Autowired
    GoodsSpecsPropValuesRepository goodsSpecsPropValuesRepository;
    @Autowired
    GoodsPropSettingRepository goodsPropSettingRepository;


    @RequestMapping("add")
    @ResponseBody
    ReplyObj add(HttpServletRequest request, @RequestParam(defaultValue = "", required = false, value = "json") String json) {
        return goodsSpecsService.add(request, json);
    }


    @RequestMapping("update")
    @ResponseBody
    ReplyObj update(HttpServletRequest request, @RequestParam(defaultValue = "", required = false, value = "json") String json) {
        return goodsSpecsService.update(request, json);
    }


    @RequestMapping("del")
    @ResponseBody
    ReplyObj del(HttpServletRequest request, @RequestParam(defaultValue = "", required = false, value = "id") String id) {
        return goodsSpecsService.del(request, id);
    }


    @RequestMapping("pageQuerySpecsAndPropByGoodsIds")
    @ResponseBody
    ReplyObj pageQuerySpecsAndPropByGoodsIds(HttpServletRequest request,
                                             @RequestParam(defaultValue = "10", required = false, value = "pageSize") int pageSize,
                                             @RequestParam(defaultValue = "1", required = false, value = "page") int page,
                                             @RequestParam(defaultValue = "", required = false, value = "goodsId") String goodsId
    ) {
        Map<String, Object> returnMap = new HashMap<>();

        if (!WebUtils.checkStr(goodsId)) {
            return WebUtils.flushFailure("数据异常，没有找到规格对应的型号");
        }

        QueryWrapper<GoodsSpecsDTO> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("goodsId", goodsId);
        queryWrapper.orderByAsc("specsSpecsValues");
        // 分页数据
        Page<GoodsSpecsDTO> returnPage = new Page<>(page, pageSize);
        IPage<GoodsSpecsDTO> iPage = pdmMapper.pageQueryGoodsSpecs(queryWrapper, returnPage);
        returnMap.put("specs", iPage);

        returnMap.put("prop", goodsSpecsPropSettingRepository.getAllData(goodsId, GoodsSpecsPropSetting.STATUS_RUNNING));

        return WebUtils.flushSuccess(returnMap);
    }


    /**
     * 使用产品编码进行检索规格属性配置
     *
     * @Author: dan
     * 修改时间: 2024/3/12
     */
    @RequestMapping("getGoodsSpecsPropByGoodsCode")
    @ResponseBody
    ReplyObj getGoodsSpecsPropByGoodsCode(HttpServletRequest request, @RequestParam(defaultValue = "", required = false, value = "goodsCode") String goodsCode
    ) {
        if (WebUtils.checkStr(goodsCode)) {
            JpaQueryBuilder pb = Specifications.<Goods>and();
            pb.eq("materialCode", goodsCode);
            String companyId = WebUtils.getSessionValue(request, WebUtils.LOGIN_COMPANY_ID_KEY);
            pb.eq("companyId", companyId);
            List<Goods> all = goodsRepository.findAll(pb.build());
            if (all.size() == 0) {
                return WebUtils.flushFailure("没有这个型号");
            }
            if (all.size() > 1) {
                return WebUtils.flushFailure("这个编码出现多个型号，存在异常，请联系管理员");
            }
            Goods goods = all.get(0);
            if (Goods.STATUS_IS_DEL.equals(goods.getStatus())) {
                return WebUtils.flushFailure("这个型号已被禁用");
            }
            if (Goods.STATUS_DELETE.equals(goods.getStatus())) {
                return WebUtils.flushFailure("这个型号已被删除");
            }
            List<Map<String, Object>> idAndName = goodsSpecsPropSettingRepository.getIdAndName(goods.getId());

            Map<String, Object> result = new HashMap<>();
            result.put("resultNames", idAndName);

            List<String> ids = idAndName.stream().map(m -> (String) m.get("id")).collect(Collectors.toList());
            List<Map<String, Object>> infoBySettingIds = goodsSpecsPropValuesRepository.getInfoBySettingIds(ids);

//            Map<String, List<Map<String, String>>> resultValues = new HashMap<>();
//            for (Map<String, Object> item : infoBySettingIds) {
//                List ppList = resultValues.get(item.get("setting_id"));
//                if (ppList == null) {
//                    ppList = new ArrayList();
//                }
//                ppList.add(item);
//                resultValues.put((String) item.get("setting_id"), ppList);
//            }
//            result.put("resultValues", resultValues);
            // 将拿到的 配置信息 按照属性配置id 进行分组, 保证每个属性配置id下的每个code的值是唯一的
            Map<String, Map<String, Map<String, Object>>> propSetMap = new HashMap<>();
            for (Map<String, Object> item : infoBySettingIds) {
                Map<String, Map<String, Object>> map = propSetMap.get(item.get("setting_id"));
                if (map == null) {
                    map = new HashMap<>();
                }
                String code = (item.get("code") != null) ? item.get("code").toString() : null;
                map.put(code, item);
                propSetMap.put((String) item.get("setting_id"), map);
            }
            // 转换成前端用的 List 的数据形式
            Map<String, List<Map<String, Object>>> resultValues = new HashMap<>();
            for (Map.Entry<String, Map<String, Map<String, Object>>> entry : propSetMap.entrySet()) {
                String key = entry.getKey();
                // 准备目标 List 数据类型
                List<Map<String, Object>> propList = new ArrayList<>();
                // 遍历值map，转换成 List
                Map<String, Map<String, Object>> value = entry.getValue();
                for (Map.Entry<String, Map<String, Object>> mapEntry : value.entrySet()) {
                    propList.add(mapEntry.getValue());
                }

                resultValues.put(key, propList);
            }

            result.put("resultValues", resultValues);

            return WebUtils.flushSuccess(result);
        } else {
            return WebUtils.flushFailure("没有这个型号");
        }
    }


    /**
     * 前端查询页查询规格，使用Mybatis的形式进行查询的方法
     *
     * @Author: dan
     * 修改时间: 2024/3/12
     */
    @RequestMapping("pageQueryGoodsSpecsList")
    @ResponseBody
    ReplyObj pageQueryGoodsSpecsList(HttpServletRequest request,
                                     @RequestParam(defaultValue = "", required = false, value = "searchValue") String searchValue,
                                     @RequestParam(defaultValue = "10", required = false, value = "pageSize") int pageSize,
                                     @RequestParam(defaultValue = "1", required = false, value = "page") int page,
                                     @RequestParam(defaultValue = "", required = false, value = "searchCode") String searchCode,
                                     @RequestParam(defaultValue = "true", required = false, value = "isProduct") Boolean isProduct,
                                     @RequestParam(defaultValue = "", required = false, value = "orderByColumn") String orderByColumn,
                                     @RequestParam(defaultValue = "true", required = false, value = "orderType") Boolean orderType
    ) {
        try {
            QueryWrapper<Map<String, Object>> query = new QueryWrapper<>();
            String companyId = WebUtils.getSessionValue(request, WebUtils.LOGIN_COMPANY_ID_KEY);
            query.eq("company_id", companyId);
            query.eq("is_product", isProduct);
            query.like("specs_sku_code", searchCode);

            if (WebUtils.checkStr(searchValue)) {
                String[] splitArray = searchValue.split("\\s+"); // 使用正则表达式\\s+作为分隔符
                for (String s : splitArray) {
                    query.and(wrapper -> wrapper
                            .like("type_name_path", s)
                            .or()
                            .like("type_code_path", s)
                            .or()
                            .like("goods_names_path", s)
                            .or()
                            .like("goods_codes_path", s)
                            .or()
                            .like("goods_name", s)
                            .or()
                            .like("goods_req_goods_name", s)
                            .or()
                            .like("specs_sku_code", s)
                            .or()
                            .like("specs_name", s)
                            .or()
                            .like("specs_names", s)
                            .or()
                            .like("specs_values", s)
                    );
                }
            }
            if (WebUtils.checkStr(orderByColumn)) {
                if (orderType) {
                    query.orderByAsc(orderByColumn);
                } else {
                    query.orderByDesc(orderByColumn);
                }
            }

            com.baomidou.mybatisplus.extension.plugins.pagination.Page<Map<String, Object>> returnPage = new com.baomidou.mybatisplus.extension.plugins.pagination.Page<>(page, pageSize);
            IPage<Map<String, Object>> iPage = pdmMapper.getGoodsSpecsList(query, returnPage);

            return WebUtils.flushSuccess(iPage);
        } catch (Exception e) {
            e.printStackTrace();
            return WebUtils.flushFailure("解析数据时出现异常");
        }
    }


    @RequestMapping("pageQuery")
    @ResponseBody
    ReplyObj pageQuery(HttpServletRequest request,
                       @RequestParam(defaultValue = "", required = false, value = "isProduct") Boolean isProduct,
                       @RequestParam(defaultValue = "", required = false, value = "isComponents") Boolean isComponents,
                       @RequestParam(defaultValue = "", required = false, value = "searchValue") String searchValue,
                       @RequestParam(defaultValue = "10", required = false, value = "pageSize") int pageSize,
                       @RequestParam(defaultValue = "1", required = false, value = "page") int page,
                       @RequestParam(defaultValue = "", required = false, value = "searchCode") String searchCode,
                       @RequestParam(defaultValue = "", required = false, value = "orderByColumn") String orderByColumn,
                       @RequestParam(defaultValue = "true", required = false, value = "orderType") Boolean orderType
    ) {
        try {
            QueryWrapper<GoodsSpecsDTO> queryWrapper = new QueryWrapper<>();

            String companyId = WebUtils.getSessionValue(request, WebUtils.LOGIN_COMPANY_ID_KEY);
            queryWrapper.eq("companyId", companyId);


            // isComponents 是 isProduct == false 时的特有产物。
            if (isProduct != null) {
                if (isProduct == true) {
                    // 选择产品
                    if (isComponents != null) {
                        // isComponents 有值, 那就要复合查询了
                        // 设置is_product和is_components的复合条件, 相当于sql: and (typeIsProduct=true or (typeIsProduct=false and typeIsComponents=#{isComponents}))
                        queryWrapper.and(
                                i -> i.eq("typeIsProduct", true)
                                        .or(j -> j.eq("typeIsProduct", false).eq("typeIsComponents", isComponents))
                        );
                    } else {
                        // isComponents 是 null, 那就只是查产品
                        queryWrapper.eq("typeIsProduct", isProduct);
                    }
                } else {
                    // 选择物料
                    queryWrapper.eq("typeIsProduct", isProduct);
                    if (isComponents != null) {
                        queryWrapper.eq("typeIsComponents", isComponents);
                    }
                }
            }


            if (WebUtils.checkStr(searchCode)) {
                queryWrapper.like("specsSkuCode", searchCode);
            }


            // 模糊查询
            if (WebUtils.checkStr(searchValue)) {
                String[] splitArray = searchValue.split("\\s+"); // 使用正则表达式\\s+作为分隔符
                for (String s : splitArray) {
                    queryWrapper.and(wrapper -> wrapper
                            .like("specsSkuCode", s)
                            .or()
                            .like("specsName", s)
                            .or()
                            .like("goodsName", s)
                            .or()
                            .like("goodsReqGoodsName", s)
                            .or()
                            .like("goodsGoodsNamesPath", s)
                            .or()
                            .like("specsCreatorName", s)
                            .or()
                            .like("specsModifierName", s)
                    );
                }
            }


            // 排序条件
            if (WebUtils.checkStr(orderByColumn)) {
                if (orderType) {
                    queryWrapper.orderByAsc(orderByColumn);
                } else {
                    queryWrapper.orderByDesc(orderByColumn);
                }
            }


            // 分页数据
            Page<GoodsSpecsDTO> returnPage = new Page<>(page, pageSize);


            IPage<GoodsSpecsDTO> iPage = pdmMapper.pageQueryGoodsSpecs(queryWrapper, returnPage);

            return WebUtils.flushSuccess(iPage);
        } catch (Exception e) {
            e.printStackTrace();
            return WebUtils.flushFailure("解析数据时出现异常");
        }
    }


    /**
     * 获取产品属性配置。主要用于 GoodsSpecsListMgr.js
     *
     * @param request
     * @param typeId
     * @return
     */
    @RequestMapping("getGoodsProp")
    @ResponseBody
    ReplyObj getGoodsProp(HttpServletRequest request, @RequestParam(defaultValue = "", required = false, value = "typeId") String typeId
    ) {
        try {
            // 根据分类id拿出所有的产品属性配置信息
            List<Map<String, Object>> idAndName = goodsPropSettingRepository.getIdAndName(typeId);
            Map<String, Object> result = new HashMap<>();
            result.put("resultNames", idAndName);

            // 提取 产品属性配置 的id列表
            List<String> ids = idAndName.stream().map(m -> (String) m.get("id")).collect(Collectors.toList());
            // 使用 产品属性配置 的id列表去查出所有的 配置信息
            List<Map<String, Object>> infoBySettingIds = goodsPropValuesRepository.getInfoBySettingIds(ids);

            // 将拿到的 配置信息 按照属性配置id 进行分组, 保证每个属性配置id下的每个code的值是唯一的
            Map<String, Map<String, Map<String, Object>>> propSetMap = new HashMap<>();
            for (Map<String, Object> item : infoBySettingIds) {
                Map<String, Map<String, Object>> map = propSetMap.get(item.get("setting_id"));
                if (map == null) {
                    map = new HashMap<>();
                }
                String code = (item.get("code") != null) ? item.get("code").toString() : null;
                map.put(code, item);
                propSetMap.put((String) item.get("setting_id"), map);
            }
            // 转换成前端用的 List 的数据形式
            Map<String, List<Map<String, Object>>> resultValues = new HashMap<>();
            for (Map.Entry<String, Map<String, Map<String, Object>>> entry : propSetMap.entrySet()) {
                String key = entry.getKey();
                // 准备目标 List 数据类型
                List<Map<String, Object>> propList = new ArrayList<>();
                // 遍历值map，转换成 List
                Map<String, Map<String, Object>> value = entry.getValue();
                for (Map.Entry<String, Map<String, Object>> mapEntry : value.entrySet()) {
                    propList.add(mapEntry.getValue());
                }

                resultValues.put(key, propList);
            }

            result.put("resultValues", resultValues);

            return WebUtils.flushSuccess(result);
        } catch (Exception e) {
            e.printStackTrace();
            return WebUtils.flushFailure("解析数据时出现异常");
        }
    }


}
